/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.dom; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.ArrayAccess; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.ArrayType; import org.eclipse.jdt.core.dom.AssertStatement; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.BlockComment; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.BooleanLiteral; import org.eclipse.jdt.core.dom.BreakStatement; import org.eclipse.jdt.core.dom.CastExpression; import org.eclipse.jdt.core.dom.CatchClause; import org.eclipse.jdt.core.dom.CharacterLiteral; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.ConditionalExpression; import org.eclipse.jdt.core.dom.ConstructorInvocation; import org.eclipse.jdt.core.dom.ContinueStatement; import org.eclipse.jdt.core.dom.DoStatement; import org.eclipse.jdt.core.dom.EmptyStatement; import org.eclipse.jdt.core.dom.EnhancedForStatement; import org.eclipse.jdt.core.dom.EnumConstantDeclaration; import org.eclipse.jdt.core.dom.EnumDeclaration; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ForStatement; import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.IfStatement; import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.InfixExpression; import org.eclipse.jdt.core.dom.Initializer; import org.eclipse.jdt.core.dom.InstanceofExpression; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.LabeledStatement; import org.eclipse.jdt.core.dom.LineComment; import org.eclipse.jdt.core.dom.MarkerAnnotation; import org.eclipse.jdt.core.dom.MemberRef; import org.eclipse.jdt.core.dom.MemberValuePair; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.MethodRef; import org.eclipse.jdt.core.dom.MethodRefParameter; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.NullLiteral; import org.eclipse.jdt.core.dom.NumberLiteral; import org.eclipse.jdt.core.dom.PackageDeclaration; import org.eclipse.jdt.core.dom.ParameterizedType; import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PostfixExpression; import org.eclipse.jdt.core.dom.PrefixExpression; import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.QualifiedType; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SimpleType; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.SwitchCase; import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.SynchronizedStatement; import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.TextElement; import org.eclipse.jdt.core.dom.ThisExpression; import org.eclipse.jdt.core.dom.ThrowStatement; import org.eclipse.jdt.core.dom.TryStatement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.TypeDeclarationStatement; import org.eclipse.jdt.core.dom.TypeLiteral; import org.eclipse.jdt.core.dom.TypeParameter; import org.eclipse.jdt.core.dom.VariableDeclarationExpression; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.core.dom.WildcardType; import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; public class ASTFlattener extends GenericVisitor { /** * The string buffer into which the serialized representation of the AST is * written. */ protected StringBuffer fBuffer; /** * Creates a new AST printer. */ public ASTFlattener() { this.fBuffer= new StringBuffer(); } /** * Returns the string accumulated in the visit. * * @return the serialized */ public String getResult() { return this.fBuffer.toString(); } /** * Resets this printer so that it can be used again. */ public void reset() { this.fBuffer.setLength(0); } public static String asString(ASTNode node) { Assert.isTrue(node.getAST().apiLevel() == ASTProvider.SHARED_AST_LEVEL); ASTFlattener flattener= new ASTFlattener(); node.accept(flattener); return flattener.getResult(); } @Override protected boolean visitNode(ASTNode node) { Assert.isTrue(false, "No implementation to flatten node: " + node.toString()); //$NON-NLS-1$ return false; } /** * Appends the text representation of the given modifier flags, followed by a single space. * Used for 3.0 modifiers and annotations. * * @param ext the list of modifier and annotation nodes * (element type: <code>IExtendedModifier</code>) */ private void printModifiers(List<IExtendedModifier> ext) { for (Iterator<IExtendedModifier> it= ext.iterator(); it.hasNext();) { ASTNode p= (ASTNode) it.next(); p.accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ } } /* * @see ASTVisitor#visit(AnnotationTypeDeclaration) * @since 3.0 */ @Override public boolean visit(AnnotationTypeDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } printModifiers(node.modifiers()); this.fBuffer.append("@interface ");//$NON-NLS-1$ node.getName().accept(this); this.fBuffer.append(" {");//$NON-NLS-1$ for (Iterator<BodyDeclaration> it= node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration d= it.next(); d.accept(this); } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration) * @since 3.0 */ @Override public boolean visit(AnnotationTypeMemberDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } printModifiers(node.modifiers()); node.getType().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ node.getName().accept(this); this.fBuffer.append("()");//$NON-NLS-1$ if (node.getDefault() != null) { this.fBuffer.append(" default ");//$NON-NLS-1$ node.getDefault().accept(this); } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(AnonymousClassDeclaration) */ @Override public boolean visit(AnonymousClassDeclaration node) { this.fBuffer.append("{");//$NON-NLS-1$ List<BodyDeclaration> bodyDeclarations= node.bodyDeclarations(); for (Iterator<BodyDeclaration> it= bodyDeclarations.iterator(); it.hasNext();) { BodyDeclaration b= it.next(); b.accept(this); } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ArrayAccess) */ @Override public boolean visit(ArrayAccess node) { node.getArray().accept(this); this.fBuffer.append("[");//$NON-NLS-1$ node.getIndex().accept(this); this.fBuffer.append("]");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ArrayCreation) */ @Override public boolean visit(ArrayCreation node) { this.fBuffer.append("new ");//$NON-NLS-1$ ArrayType at= node.getType(); int dims= at.getDimensions(); Type elementType= at.getElementType(); elementType.accept(this); for (Iterator<Expression> it= node.dimensions().iterator(); it.hasNext();) { this.fBuffer.append("[");//$NON-NLS-1$ Expression e= it.next(); e.accept(this); this.fBuffer.append("]");//$NON-NLS-1$ dims--; } // add empty "[]" for each extra array dimension for (int i= 0; i < dims; i++) { this.fBuffer.append("[]");//$NON-NLS-1$ } if (node.getInitializer() != null) { node.getInitializer().accept(this); } return false; } /* * @see ASTVisitor#visit(ArrayInitializer) */ @Override public boolean visit(ArrayInitializer node) { this.fBuffer.append("{");//$NON-NLS-1$ for (Iterator<Expression> it= node.expressions().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ArrayType) */ @Override public boolean visit(ArrayType node) { node.getComponentType().accept(this); this.fBuffer.append("[]");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(AssertStatement) */ @Override public boolean visit(AssertStatement node) { this.fBuffer.append("assert ");//$NON-NLS-1$ node.getExpression().accept(this); if (node.getMessage() != null) { this.fBuffer.append(" : ");//$NON-NLS-1$ node.getMessage().accept(this); } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(Assignment) */ @Override public boolean visit(Assignment node) { node.getLeftHandSide().accept(this); this.fBuffer.append(node.getOperator().toString()); node.getRightHandSide().accept(this); return false; } /* * @see ASTVisitor#visit(Block) */ @Override public boolean visit(Block node) { this.fBuffer.append("{");//$NON-NLS-1$ for (Iterator<Statement> it= node.statements().iterator(); it.hasNext();) { Statement s= it.next(); s.accept(this); } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(BlockComment) * @since 3.0 */ @Override public boolean visit(BlockComment node) { this.fBuffer.append("/* */");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(BooleanLiteral) */ @Override public boolean visit(BooleanLiteral node) { if (node.booleanValue() == true) { this.fBuffer.append("true");//$NON-NLS-1$ } else { this.fBuffer.append("false");//$NON-NLS-1$ } return false; } /* * @see ASTVisitor#visit(BreakStatement) */ @Override public boolean visit(BreakStatement node) { this.fBuffer.append("break");//$NON-NLS-1$ if (node.getLabel() != null) { this.fBuffer.append(" ");//$NON-NLS-1$ node.getLabel().accept(this); } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(CastExpression) */ @Override public boolean visit(CastExpression node) { this.fBuffer.append("(");//$NON-NLS-1$ node.getType().accept(this); this.fBuffer.append(")");//$NON-NLS-1$ node.getExpression().accept(this); return false; } /* * @see ASTVisitor#visit(CatchClause) */ @Override public boolean visit(CatchClause node) { this.fBuffer.append("catch (");//$NON-NLS-1$ node.getException().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(CharacterLiteral) */ @Override public boolean visit(CharacterLiteral node) { this.fBuffer.append(node.getEscapedValue()); return false; } /* * @see ASTVisitor#visit(ClassInstanceCreation) */ @Override public boolean visit(ClassInstanceCreation node) { if (node.getExpression() != null) { node.getExpression().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } this.fBuffer.append("new ");//$NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } node.getType().accept(this); } this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ if (node.getAnonymousClassDeclaration() != null) { node.getAnonymousClassDeclaration().accept(this); } return false; } /* * @see ASTVisitor#visit(CompilationUnit) */ @Override public boolean visit(CompilationUnit node) { if (node.getPackage() != null) { node.getPackage().accept(this); } for (Iterator<ImportDeclaration> it= node.imports().iterator(); it.hasNext();) { ImportDeclaration d= it.next(); d.accept(this); } for (Iterator<AbstractTypeDeclaration> it= node.types().iterator(); it.hasNext();) { AbstractTypeDeclaration d= it.next(); d.accept(this); } return false; } /* * @see ASTVisitor#visit(ConditionalExpression) */ @Override public boolean visit(ConditionalExpression node) { node.getExpression().accept(this); this.fBuffer.append("?");//$NON-NLS-1$ node.getThenExpression().accept(this); this.fBuffer.append(":");//$NON-NLS-1$ node.getElseExpression().accept(this); return false; } /* * @see ASTVisitor#visit(ConstructorInvocation) */ @Override public boolean visit(ConstructorInvocation node) { if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } } this.fBuffer.append("this(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(");");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ContinueStatement) */ @Override public boolean visit(ContinueStatement node) { this.fBuffer.append("continue");//$NON-NLS-1$ if (node.getLabel() != null) { this.fBuffer.append(" ");//$NON-NLS-1$ node.getLabel().accept(this); } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(DoStatement) */ @Override public boolean visit(DoStatement node) { this.fBuffer.append("do ");//$NON-NLS-1$ node.getBody().accept(this); this.fBuffer.append(" while (");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(");");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(EmptyStatement) */ @Override public boolean visit(EmptyStatement node) { this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(EnhancedForStatement) * @since 3.0 */ @Override public boolean visit(EnhancedForStatement node) { this.fBuffer.append("for (");//$NON-NLS-1$ node.getParameter().accept(this); this.fBuffer.append(" : ");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(EnumConstantDeclaration) * @since 3.0 */ @Override public boolean visit(EnumConstantDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } printModifiers(node.modifiers()); node.getName().accept(this); if (!node.arguments().isEmpty()) { this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ } if (node.getAnonymousClassDeclaration() != null) { node.getAnonymousClassDeclaration().accept(this); } return false; } /* * @see ASTVisitor#visit(EnumDeclaration) * @since 3.0 */ @Override public boolean visit(EnumDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } printModifiers(node.modifiers()); this.fBuffer.append("enum ");//$NON-NLS-1$ node.getName().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ if (!node.superInterfaceTypes().isEmpty()) { this.fBuffer.append("implements ");//$NON-NLS-1$ for (Iterator<Type> it= node.superInterfaceTypes().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(" ");//$NON-NLS-1$ } this.fBuffer.append("{");//$NON-NLS-1$ for (Iterator<EnumConstantDeclaration> it = node.enumConstants().iterator(); it.hasNext(); ) { EnumConstantDeclaration d = it.next(); d.accept(this); // enum constant declarations do not include punctuation if (it.hasNext()) { // enum constant declarations are separated by commas this.fBuffer.append(", ");//$NON-NLS-1$ } } if (!node.bodyDeclarations().isEmpty()) { this.fBuffer.append("; ");//$NON-NLS-1$ for (Iterator<BodyDeclaration> it = node.bodyDeclarations().iterator(); it.hasNext(); ) { BodyDeclaration d = it.next(); d.accept(this); // other body declarations include trailing punctuation } } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ExpressionStatement) */ @Override public boolean visit(ExpressionStatement node) { node.getExpression().accept(this); this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(FieldAccess) */ @Override public boolean visit(FieldAccess node) { node.getExpression().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ node.getName().accept(this); return false; } /* * @see ASTVisitor#visit(FieldDeclaration) */ @Override public boolean visit(FieldDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } node.getType().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f= it.next(); f.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ForStatement) */ @Override public boolean visit(ForStatement node) { this.fBuffer.append("for (");//$NON-NLS-1$ for (Iterator<Expression> it= node.initializers().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); } this.fBuffer.append("; ");//$NON-NLS-1$ if (node.getExpression() != null) { node.getExpression().accept(this); } this.fBuffer.append("; ");//$NON-NLS-1$ for (Iterator<Expression> it= node.updaters().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); } this.fBuffer.append(") ");//$NON-NLS-1$ node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(IfStatement) */ @Override public boolean visit(IfStatement node) { this.fBuffer.append("if (");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ node.getThenStatement().accept(this); if (node.getElseStatement() != null) { this.fBuffer.append(" else ");//$NON-NLS-1$ node.getElseStatement().accept(this); } return false; } /* * @see ASTVisitor#visit(ImportDeclaration) */ @Override public boolean visit(ImportDeclaration node) { this.fBuffer.append("import ");//$NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS3) { if (node.isStatic()) { this.fBuffer.append("static ");//$NON-NLS-1$ } } node.getName().accept(this); if (node.isOnDemand()) { this.fBuffer.append(".*");//$NON-NLS-1$ } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(InfixExpression) */ @Override public boolean visit(InfixExpression node) { node.getLeftOperand().accept(this); this.fBuffer.append(' '); // for cases like x= i - -1; or x= i++ + ++i; this.fBuffer.append(node.getOperator().toString()); this.fBuffer.append(' '); node.getRightOperand().accept(this); final List<Expression>extendedOperands = node.extendedOperands(); if (extendedOperands.size() != 0) { this.fBuffer.append(' '); for (Iterator<Expression> it = extendedOperands.iterator(); it.hasNext(); ) { this.fBuffer.append(node.getOperator().toString()).append(' '); Expression e = it.next(); e.accept(this); } } return false; } /* * @see ASTVisitor#visit(InstanceofExpression) */ @Override public boolean visit(InstanceofExpression node) { node.getLeftOperand().accept(this); this.fBuffer.append(" instanceof ");//$NON-NLS-1$ node.getRightOperand().accept(this); return false; } /* * @see ASTVisitor#visit(Initializer) */ @Override public boolean visit(Initializer node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(Javadoc) */ @Override public boolean visit(Javadoc node) { this.fBuffer.append("/** ");//$NON-NLS-1$ for (Iterator<TagElement> it= node.tags().iterator(); it.hasNext();) { ASTNode e= it.next(); e.accept(this); } this.fBuffer.append("\n */");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(LabeledStatement) */ @Override public boolean visit(LabeledStatement node) { node.getLabel().accept(this); this.fBuffer.append(": ");//$NON-NLS-1$ node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(LineComment) * @since 3.0 */ @Override public boolean visit(LineComment node) { this.fBuffer.append("//\n");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(MarkerAnnotation) * @since 3.0 */ @Override public boolean visit(MarkerAnnotation node) { this.fBuffer.append("@");//$NON-NLS-1$ node.getTypeName().accept(this); return false; } /* * @see ASTVisitor#visit(MemberRef) * @since 3.0 */ @Override public boolean visit(MemberRef node) { if (node.getQualifier() != null) { node.getQualifier().accept(this); } this.fBuffer.append("#");//$NON-NLS-1$ node.getName().accept(this); return false; } /* * @see ASTVisitor#visit(MemberValuePair) * @since 3.0 */ @Override public boolean visit(MemberValuePair node) { node.getName().accept(this); this.fBuffer.append("=");//$NON-NLS-1$ node.getValue().accept(this); return false; } /* * @see ASTVisitor#visit(MethodRef) * @since 3.0 */ @Override public boolean visit(MethodRef node) { if (node.getQualifier() != null) { node.getQualifier().accept(this); } this.fBuffer.append("#");//$NON-NLS-1$ node.getName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<MethodRefParameter> it= node.parameters().iterator(); it.hasNext();) { MethodRefParameter e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(MethodRefParameter) * @since 3.0 */ @Override public boolean visit(MethodRefParameter node) { node.getType().accept(this); if (node.getAST().apiLevel() >= AST.JLS3) { if (node.isVarargs()) { this.fBuffer.append("...");//$NON-NLS-1$ } } if (node.getName() != null) { this.fBuffer.append(" ");//$NON-NLS-1$ node.getName().accept(this); } return false; } /* * @see ASTVisitor#visit(MethodDeclaration) */ @Override public boolean visit(MethodDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); if (!node.typeParameters().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<TypeParameter> it= node.typeParameters().iterator(); it.hasNext();) { TypeParameter t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append("> ");//$NON-NLS-1$ } } if (!node.isConstructor()) { if (node.getReturnType2() != null) { node.getReturnType2().accept(this); } else { // methods really ought to have a return type this.fBuffer.append("void");//$NON-NLS-1$ } this.fBuffer.append(" ");//$NON-NLS-1$ } node.getName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<SingleVariableDeclaration> it= node.parameters().iterator(); it.hasNext();) { SingleVariableDeclaration v= it.next(); v.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ for (int i= 0; i < node.getExtraDimensions(); i++) { this.fBuffer.append("[]"); //$NON-NLS-1$ } if (!node.thrownExceptions().isEmpty()) { this.fBuffer.append(" throws ");//$NON-NLS-1$ for (Iterator<Name> it= node.thrownExceptions().iterator(); it.hasNext();) { Name n= it.next(); n.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(" ");//$NON-NLS-1$ } if (node.getBody() == null) { this.fBuffer.append(";");//$NON-NLS-1$ } else { node.getBody().accept(this); } return false; } /* * @see ASTVisitor#visit(MethodInvocation) */ @Override public boolean visit(MethodInvocation node) { if (node.getExpression() != null) { node.getExpression().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } } node.getName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(Modifier) * @since 3.0 */ @Override public boolean visit(Modifier node) { this.fBuffer.append(node.getKeyword().toString()); return false; } /* * @see ASTVisitor#visit(NormalAnnotation) * @since 3.0 */ @Override public boolean visit(NormalAnnotation node) { this.fBuffer.append("@");//$NON-NLS-1$ node.getTypeName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<MemberValuePair> it= node.values().iterator(); it.hasNext();) { MemberValuePair p= it.next(); p.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(NullLiteral) */ @Override public boolean visit(NullLiteral node) { this.fBuffer.append("null");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(NumberLiteral) */ @Override public boolean visit(NumberLiteral node) { this.fBuffer.append(node.getToken()); return false; } /* * @see ASTVisitor#visit(PackageDeclaration) */ @Override public boolean visit(PackageDeclaration node) { if (node.getAST().apiLevel() >= AST.JLS3) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } for (Iterator<Annotation> it= node.annotations().iterator(); it.hasNext();) { Annotation p= it.next(); p.accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ } } this.fBuffer.append("package ");//$NON-NLS-1$ node.getName().accept(this); this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ParameterizedType) * @since 3.0 */ @Override public boolean visit(ParameterizedType node) { node.getType().accept(this); this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ParenthesizedExpression) */ @Override public boolean visit(ParenthesizedExpression node) { this.fBuffer.append("(");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(PostfixExpression) */ @Override public boolean visit(PostfixExpression node) { node.getOperand().accept(this); this.fBuffer.append(node.getOperator().toString()); return false; } /* * @see ASTVisitor#visit(PrefixExpression) */ @Override public boolean visit(PrefixExpression node) { this.fBuffer.append(node.getOperator().toString()); node.getOperand().accept(this); return false; } /* * @see ASTVisitor#visit(PrimitiveType) */ @Override public boolean visit(PrimitiveType node) { this.fBuffer.append(node.getPrimitiveTypeCode().toString()); return false; } /* * @see ASTVisitor#visit(QualifiedName) */ @Override public boolean visit(QualifiedName node) { node.getQualifier().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ node.getName().accept(this); return false; } /* * @see ASTVisitor#visit(QualifiedType) * @since 3.0 */ @Override public boolean visit(QualifiedType node) { node.getQualifier().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ node.getName().accept(this); return false; } /* * @see ASTVisitor#visit(ReturnStatement) */ @Override public boolean visit(ReturnStatement node) { this.fBuffer.append("return");//$NON-NLS-1$ if (node.getExpression() != null) { this.fBuffer.append(" ");//$NON-NLS-1$ node.getExpression().accept(this); } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(SimpleName) */ @Override public boolean visit(SimpleName node) { this.fBuffer.append(node.getIdentifier()); return false; } /* * @see ASTVisitor#visit(SimpleType) */ @Override public boolean visit(SimpleType node) { return true; } /* * @see ASTVisitor#visit(SingleMemberAnnotation) * @since 3.0 */ @Override public boolean visit(SingleMemberAnnotation node) { this.fBuffer.append("@");//$NON-NLS-1$ node.getTypeName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ node.getValue().accept(this); this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(SingleVariableDeclaration) */ @Override public boolean visit(SingleVariableDeclaration node) { if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } node.getType().accept(this); if (node.getAST().apiLevel() >= AST.JLS3) { if (node.isVarargs()) { this.fBuffer.append("...");//$NON-NLS-1$ } } this.fBuffer.append(" ");//$NON-NLS-1$ node.getName().accept(this); for (int i= 0; i < node.getExtraDimensions(); i++) { this.fBuffer.append("[]"); //$NON-NLS-1$ } if (node.getInitializer() != null) { this.fBuffer.append("=");//$NON-NLS-1$ node.getInitializer().accept(this); } return false; } /* * @see ASTVisitor#visit(StringLiteral) */ @Override public boolean visit(StringLiteral node) { this.fBuffer.append(node.getEscapedValue()); return false; } /* * @see ASTVisitor#visit(SuperConstructorInvocation) */ @Override public boolean visit(SuperConstructorInvocation node) { if (node.getExpression() != null) { node.getExpression().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } } this.fBuffer.append("super(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(");");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(SuperFieldAccess) */ @Override public boolean visit(SuperFieldAccess node) { if (node.getQualifier() != null) { node.getQualifier().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } this.fBuffer.append("super.");//$NON-NLS-1$ node.getName().accept(this); return false; } /* * @see ASTVisitor#visit(SuperMethodInvocation) */ @Override public boolean visit(SuperMethodInvocation node) { if (node.getQualifier() != null) { node.getQualifier().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } this.fBuffer.append("super.");//$NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<Type> it= node.typeArguments().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } } node.getName().accept(this); this.fBuffer.append("(");//$NON-NLS-1$ for (Iterator<Expression> it= node.arguments().iterator(); it.hasNext();) { Expression e= it.next(); e.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(")");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(SwitchCase) */ @Override public boolean visit(SwitchCase node) { if (node.isDefault()) { this.fBuffer.append("default :");//$NON-NLS-1$ } else { this.fBuffer.append("case ");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(":");//$NON-NLS-1$ } return false; } /* * @see ASTVisitor#visit(SwitchStatement) */ @Override public boolean visit(SwitchStatement node) { this.fBuffer.append("switch (");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ this.fBuffer.append("{");//$NON-NLS-1$ for (Iterator<Statement> it= node.statements().iterator(); it.hasNext();) { Statement s= it.next(); s.accept(this); } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(SynchronizedStatement) */ @Override public boolean visit(SynchronizedStatement node) { this.fBuffer.append("synchronized (");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ node.getBody().accept(this); return false; } /* * @see ASTVisitor#visit(TagElement) * @since 3.0 */ @Override public boolean visit(TagElement node) { if (node.isNested()) { // nested tags are always enclosed in braces this.fBuffer.append("{");//$NON-NLS-1$ } else { // top-level tags always begin on a new line this.fBuffer.append("\n * ");//$NON-NLS-1$ } boolean previousRequiresWhiteSpace= false; if (node.getTagName() != null) { this.fBuffer.append(node.getTagName()); previousRequiresWhiteSpace= true; } boolean previousRequiresNewLine= false; for (Iterator<? extends ASTNode> it= node.fragments().iterator(); it.hasNext();) { ASTNode e= it.next(); // assume text elements include necessary leading and trailing whitespace // but Name, MemberRef, MethodRef, and nested TagElement do not include white space boolean currentIncludesWhiteSpace= (e instanceof TextElement); if (previousRequiresNewLine && currentIncludesWhiteSpace) { this.fBuffer.append("\n * ");//$NON-NLS-1$ } previousRequiresNewLine= currentIncludesWhiteSpace; // add space if required to separate if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) { this.fBuffer.append(" "); //$NON-NLS-1$ } e.accept(this); previousRequiresWhiteSpace= !currentIncludesWhiteSpace && !(e instanceof TagElement); } if (node.isNested()) { this.fBuffer.append("}");//$NON-NLS-1$ } return false; } /* * @see ASTVisitor#visit(TextElement) * @since 3.0 */ @Override public boolean visit(TextElement node) { this.fBuffer.append(node.getText()); return false; } /* * @see ASTVisitor#visit(ThisExpression) */ @Override public boolean visit(ThisExpression node) { if (node.getQualifier() != null) { node.getQualifier().accept(this); this.fBuffer.append(".");//$NON-NLS-1$ } this.fBuffer.append("this");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(ThrowStatement) */ @Override public boolean visit(ThrowStatement node) { this.fBuffer.append("throw ");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(TryStatement) */ @Override public boolean visit(TryStatement node) { this.fBuffer.append("try ");//$NON-NLS-1$ node.getBody().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ for (Iterator<CatchClause> it= node.catchClauses().iterator(); it.hasNext();) { CatchClause cc= it.next(); cc.accept(this); } if (node.getFinally() != null) { this.fBuffer.append("finally ");//$NON-NLS-1$ node.getFinally().accept(this); } return false; } /* * @see ASTVisitor#visit(TypeDeclaration) */ @Override public boolean visit(TypeDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } this.fBuffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$ node.getName().accept(this); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeParameters().isEmpty()) { this.fBuffer.append("<");//$NON-NLS-1$ for (Iterator<TypeParameter> it= node.typeParameters().iterator(); it.hasNext();) { TypeParameter t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(",");//$NON-NLS-1$ } } this.fBuffer.append(">");//$NON-NLS-1$ } } this.fBuffer.append(" ");//$NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS3) { if (node.getSuperclassType() != null) { this.fBuffer.append("extends ");//$NON-NLS-1$ node.getSuperclassType().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ } if (!node.superInterfaceTypes().isEmpty()) { this.fBuffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$ for (Iterator<Type> it= node.superInterfaceTypes().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(" ");//$NON-NLS-1$ } } this.fBuffer.append("{");//$NON-NLS-1$ BodyDeclaration prev= null; for (Iterator<BodyDeclaration> it= node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration d= it.next(); if (prev instanceof EnumConstantDeclaration) { // enum constant declarations do not include punctuation if (d instanceof EnumConstantDeclaration) { // enum constant declarations are separated by commas this.fBuffer.append(", ");//$NON-NLS-1$ } else { // semicolon separates last enum constant declaration from // first class body declarations this.fBuffer.append("; ");//$NON-NLS-1$ } } d.accept(this); prev= d; } this.fBuffer.append("}");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(TypeDeclarationStatement) */ @Override public boolean visit(TypeDeclarationStatement node) { if (node.getAST().apiLevel() >= AST.JLS3) { node.getDeclaration().accept(this); } return false; } /* * @see ASTVisitor#visit(TypeLiteral) */ @Override public boolean visit(TypeLiteral node) { node.getType().accept(this); this.fBuffer.append(".class");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(TypeParameter) * @since 3.0 */ @Override public boolean visit(TypeParameter node) { node.getName().accept(this); if (!node.typeBounds().isEmpty()) { this.fBuffer.append(" extends ");//$NON-NLS-1$ for (Iterator<Type> it= node.typeBounds().iterator(); it.hasNext();) { Type t= it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(" & ");//$NON-NLS-1$ } } } return false; } /* * @see ASTVisitor#visit(VariableDeclarationExpression) */ @Override public boolean visit(VariableDeclarationExpression node) { if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } node.getType().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f= it.next(); f.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } return false; } /* * @see ASTVisitor#visit(VariableDeclarationFragment) */ @Override public boolean visit(VariableDeclarationFragment node) { node.getName().accept(this); for (int i= 0; i < node.getExtraDimensions(); i++) { this.fBuffer.append("[]");//$NON-NLS-1$ } if (node.getInitializer() != null) { this.fBuffer.append("=");//$NON-NLS-1$ node.getInitializer().accept(this); } return false; } /* * @see ASTVisitor#visit(VariableDeclarationStatement) */ @Override public boolean visit(VariableDeclarationStatement node) { if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); } node.getType().accept(this); this.fBuffer.append(" ");//$NON-NLS-1$ for (Iterator<VariableDeclarationFragment> it= node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f= it.next(); f.accept(this); if (it.hasNext()) { this.fBuffer.append(", ");//$NON-NLS-1$ } } this.fBuffer.append(";");//$NON-NLS-1$ return false; } /* * @see ASTVisitor#visit(WildcardType) * @since 3.0 */ @Override public boolean visit(WildcardType node) { this.fBuffer.append("?");//$NON-NLS-1$ Type bound= node.getBound(); if (bound != null) { if (node.isUpperBound()) { this.fBuffer.append(" extends ");//$NON-NLS-1$ } else { this.fBuffer.append(" super ");//$NON-NLS-1$ } bound.accept(this); } return false; } /* * @see ASTVisitor#visit(WhileStatement) */ @Override public boolean visit(WhileStatement node) { this.fBuffer.append("while (");//$NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") ");//$NON-NLS-1$ node.getBody().accept(this); return false; } }